const Keys = require('../template')

console.log("=== Keys 基础测试 ===")

// 测试基本对象键获取
console.log(
  "基本对象键获取:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 3 &&
      keys.includes('a') &&
      keys.includes('b') &&
      keys.includes('c')
  })()
)

// 测试空对象键获取
console.log(
  "空对象键获取:", (() => {
    const obj = {}
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 0
  })()
)

// 测试嵌套对象键获取
console.log(
  "嵌套对象键获取:", (() => {
    const obj = { a: { b: 1 }, c: { d: 2 } }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('a') &&
      keys.includes('c')
  })()
)

// 测试数组对象键获取
console.log(
  "数组对象键获取:", (() => {
    const obj = { users: [1, 2, 3], posts: [4, 5, 6] }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('users') &&
      keys.includes('posts')
  })()
)

// 测试数字键获取
console.log(
  "数字键获取:", (() => {
    const obj = { 0: 'zero', 1: 'one', 2: 'two' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 3 &&
      keys.includes('0') &&
      keys.includes('1') &&
      keys.includes('2')
  })()
)

// 测试特殊字符键获取
console.log(
  "特殊字符键获取:", (() => {
    const obj = { 'key-with-dash': 'value1', 'key.with.dot': 'value2', 'key with space': 'value3' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 3 &&
      keys.includes('key-with-dash') &&
      keys.includes('key.with.dot') &&
      keys.includes('key with space')
  })()
)

// 测试布尔值键获取
console.log(
  "布尔值键获取:", (() => {
    const obj = { true: 'yes', false: 'no' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('true') &&
      keys.includes('false')
  })()
)

// 测试空字符串键获取
console.log(
  "空字符串键获取:", (() => {
    const obj = { '': 'empty key', 'a': 'normal key' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('') &&
      keys.includes('a')
  })()
)

// 测试函数值键获取
console.log(
  "函数值键获取:", (() => {
    const func = () => 'hello'
    const obj = { method: func, data: 'value' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('method') &&
      keys.includes('data')
  })()
)

// 测试对象值键获取
console.log(
  "对象值键获取:", (() => {
    const nested = { value: 'nested' }
    const obj = { nested: nested, simple: 'value' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('nested') &&
      keys.includes('simple')
  })()
)

// 测试数组值键获取
console.log(
  "数组值键获取:", (() => {
    const arr = [1, 2, 3]
    const obj = { items: arr, count: 3 }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('items') &&
      keys.includes('count')
  })()
)

// 测试null值键获取
console.log(
  "null值键获取:", (() => {
    const obj = { nullValue: null, normalValue: 'test' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('nullValue') &&
      keys.includes('normalValue')
  })()
)

// 测试undefined值键获取
console.log(
  "undefined值键获取:", (() => {
    const obj = { undefinedValue: undefined, normalValue: 'test' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('undefinedValue') &&
      keys.includes('normalValue')
  })()
)

// 测试复杂对象键获取
console.log(
  "复杂对象键获取:", (() => {
    const obj = {
      user: { name: 'John', age: 30 },
      posts: [{ title: 'Post 1' }, { title: 'Post 2' }],
      meta: { count: 2 },
      settings: { theme: 'dark' }
    }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 4 &&
      keys.includes('user') &&
      keys.includes('posts') &&
      keys.includes('meta') &&
      keys.includes('settings')
  })()
)

// 测试原型链属性键获取
console.log(
  "原型链属性键获取:", (() => {
    function TestClass() {
      this.instanceProp = 'instance'
    }
    TestClass.prototype.prototypeProp = 'prototype'

    const instance = new TestClass()
    const keys = Keys.keys(instance)

    return Array.isArray(keys) &&
      keys.length === 1 &&
      keys.includes('instanceProp') &&
      !keys.includes('prototypeProp') // 只获取自有属性
  })()
)

// 测试Symbol键获取
console.log(
  "Symbol键获取:", (() => {
    const sym = Symbol('test')
    const obj = { [sym]: 'symbol value', normal: 'normal value' }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 1 &&
      keys.includes('normal') &&
      !keys.includes(sym) // Symbol键通常不包含在keys中
  })()
)

// 测试不可枚举属性键获取
console.log(
  "不可枚举属性键获取:", (() => {
    const obj = { a: 1, b: 2 }
    Object.defineProperty(obj, 'c', {
      value: 3,
      enumerable: false
    })
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 2 &&
      keys.includes('a') &&
      keys.includes('b') &&
      !keys.includes('c') // 不可枚举属性不包含
  })()
)

// 测试null对象键获取
console.log(
  "null对象键获取:", (() => {
    const obj = null
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 0
  })()
)

// 测试undefined对象键获取
console.log(
  "undefined对象键获取:", (() => {
    const obj = undefined
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 0
  })()
)

// 测试非对象键获取
console.log(
  "非对象键获取:", (() => {
    const keys1 = Keys.keys('string')
    const keys2 = Keys.keys(42)
    const keys3 = Keys.keys(true)

    return Array.isArray(keys1) &&
      keys1.length === 0 &&
      Array.isArray(keys2) &&
      keys2.length === 0 &&
      Array.isArray(keys3) &&
      keys3.length === 0
  })()
)

// 测试数组键获取
console.log(
  "数组键获取:", (() => {
    const arr = [1, 2, 3]
    const keys = Keys.keys(arr)

    return Array.isArray(keys) &&
      keys.length === 3 &&
      keys.includes('0') &&
      keys.includes('1') &&
      keys.includes('2')
  })()
)

// 测试函数键获取
console.log(
  "函数键获取:", (() => {
    const func = function test() { return 'hello' }
    const keys = Keys.keys(func)

    return Array.isArray(keys) &&
      keys.length === 0 // 函数通常没有可枚举属性
  })()
)

// 测试Date对象键获取
console.log(
  "Date对象键获取:", (() => {
    const date = new Date()
    const keys = Keys.keys(date)

    return Array.isArray(keys) &&
      keys.length === 0 // Date对象通常没有可枚举属性
  })()
)

// 测试RegExp对象键获取
console.log(
  "RegExp对象键获取:", (() => {
    const regex = /test/gi
    const keys = Keys.keys(regex)

    return Array.isArray(keys) &&
      keys.length === 0 // RegExp对象通常没有可枚举属性
  })()
)

// 测试Map对象键获取
console.log(
  "Map对象键获取:", (() => {
    const map = new Map([['a', 1], ['b', 2]])
    const keys = Keys.keys(map)

    return Array.isArray(keys) &&
      keys.length === 0 // Map对象通常没有可枚举属性
  })()
)

// 测试Set对象键获取
console.log(
  "Set对象键获取:", (() => {
    const set = new Set([1, 2, 3])
    const keys = Keys.keys(set)

    return Array.isArray(keys) &&
      keys.length === 0 // Set对象通常没有可枚举属性
  })()
)

// 测试键的顺序
console.log(
  "键的顺序:", (() => {
    const obj = { c: 3, a: 1, b: 2 }
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 3 &&
      keys[0] === 'c' &&
      keys[1] === 'a' &&
      keys[2] === 'b'
  })()
)

// 测试重复键获取
console.log(
  "重复键获取:", (() => {
    const obj = { a: 1, a: 2 } // 后面的会覆盖前面的
    const keys = Keys.keys(obj)

    return Array.isArray(keys) &&
      keys.length === 1 &&
      keys.includes('a')
  })()
)

console.log("=== Keys 基础测试完成 ===")
